/*movietech.c*/
#include "cineplex.h"

void MovieTech_Scheduler()
{
	agentsStarted = agentsStarted + 1;
	Wait(initCond, initLock);
	tech.runScheduler = runSchedulers;
	do
	{
		/*printf("%s running Scheduler...\n",myName);*/
	
		Acquire(tech.msgLock);
		if(tech.status == IDLE)
		{
			MovieTech_GetMessage(StartMovie);
			if(lobby.tempMsg.sender != NullMsg)
			{
				Release(tech.msgLock);
				MovieTech_CheckWithLobby();
				continue;
			}
		}
		else if(tech.status == WAITINGFORLOBBY)
		{
			/*if(msgList->Find("LobbyEmpty"))*/
			MovieTech_GetMessage(LobbyEmpty);
			if(lobby.tempMsg.sender != NullMsg)
			{
				MovieTech_AskTakerAboutLine();
				Release(tech.msgLock);
				continue;
			}
		}
		else if(tech.status == WAITINGFORTAKERS)
		{
			/*if(msgList->Find("LineIsEmpty"))*/
			MovieTech_GetMessage(LineIsEmpty);
			if(lobby.tempMsg.sender != NullMsg)
			{
				MovieTech_TakerIsGood();
				Release(tech.msgLock);
				continue;
			}
		}
		else if(tech.status == STARTINGMOVIE)
		{
			MovieTech_PlayMovie();
			Release(tech.msgLock);
			continue;
		}
		else if(tech.status == MOVIEOVER)
		{
			MovieTech_EndMovie();
			Release(tech.msgLock);
			continue;
		}
		/*printf("%s is sleeping...\n",myName);*/
		Wait(tech.sleepCon, tech.msgLock);
	} while(tech.runScheduler);
}

struct Message MovieTech_GetMessage(int name)
{
	/*this will be the null output*/
	tech.tempMsg.name = NullMsg;
	tech.tempMsg.sender = NullMsg;
	
	Acquire(loopLock);
	for(i = 0; i < tech.numMsgs; i++)
	{
		if(tech.msgList[i].name == name)
		{
			tech.tempMsg.name = name;
			tech.tempMsg.sender = tech.msgList[i].sender;
			tech.numMsgs = tech.numMsgs - 1;
			break;
		}
	}
	for(k = i; k < 2; k++)
	{
		/*movin on up*/
		tech.msgList[k].name = tech.msgList[k+1].name;
		tech.msgList[k].sender = tech.msgList[k+1].sender;
	}
	tech.msgList[2].name = NullMsg;
	tech.msgList[2].sender = NullMsg;
	Release(loopLock);
		
	return tech.tempMsg;
}

void MovieTech_CheckWithLobby()
{
	/*make sure at least one person has entered before seeing if everyone has*/
	while(seatsFilled == 0)
	{
		/*getCineplex()->waitNotEmpty->Wait(msgLock);//getCineplex()->theater->seatingLock);*/
		/*printf("%s has awoken\n",myName);*/
		if(customersRunning!=0)
		{
			Yield();
		}
		else
		{
			Exit(0);
		}
	}
	/*printf("asking if lobby is idle\n");*/
	/*getCineplex()->lobby->SendMessage("AreYouIdle",1,this);*/
	SendMessage(T_LOBBY, 0, AreYouIdle, 0);
	tech.status = WAITINGFORLOBBY;
}

void MovieTech_AskTakerAboutLine()
{
	/*printf("asking takers about lines\n");*/
	int tmp=0;
	while(tmp < NUM_TIX_TAKERS)
	{
		/*taker->SendMessage("IsYourLineEmpty",1,this);*/
		SendMessage(T_TICKETTAKER, tmp, IsYourLineEmpty, 0);
		tmp++;
	}
	tech.numTakersReplyNeeded = NUM_TIX_TAKERS;
	tech.status=WAITINGFORTAKERS;
}

void MovieTech_TakerIsGood()
{
	tech.numTakersReplyNeeded = tech.numTakersReplyNeeded-1;
	/*printf("%s sees a TT is clear\n",myName);*/
	if(tech.numTakersReplyNeeded<=0)
	{
		tech.status=STARTINGMOVIE;
	}
}

void MovieTech_PlayMovie()
{
	/*printf("The MovieTechnician has started the movie.\n");*/
	int movieLength = 0;
	int playtime = 0;
	movieStarted=1;
	letPeopleIn = 0;
	movieLength=200+getRandPercent();
	
	for(playtime=0;playtime<movieLength;playtime++)
	{
		Yield();
	}
	tech.status=MOVIEOVER;
}

void MovieTech_EndMovie()
{
	/*printf("The MovieTechnician has ended the movie.\n");*/
	
	Acquire(seatingLock);
	Acquire(loopLock);
	for(i=0;i<totalSeats;i++)
	{
		k = seating[i]; /*get customer in seat*/
		if(k != -1)
		{
			/*cust->SendMessage("MovieIsDone",0);*/
			SendMessage(T_CUSTOMER, k, MovieIsDone, 0);
			seating[i] = -1;
		}
	}
	Release(loopLock);
	Release(seatingLock);
	/*printf("The MovieTechnician has told all customers to leave the theater room.\n");*/
	movieStarted=0;
	/*getCineplex()->manager->SendMessage("MovieOver",0);*/
	SendMessage(T_MANAGER, 0, MovieOver, 0);
	tech.status=IDLE;
}
